home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / qsort.arc / QSORT.DOC < prev   
Encoding:
Text File  |  1985-06-30  |  14.9 KB  |  320 lines

  1. QSORT - Version 1.2 - Copyright (c) 1985 - Ben Baker
  2.  
  3.  
  4. QSORT   may  be  freely  copied  and  distributed  for  non-
  5. commercial purposes, provided  that  1)  it  is  distributed
  6. under  the  name  "QSORT,"  and  2)  this documentation file
  7. always accompanies it.  Vendors wishing to distribute  QSORT
  8. commercially,  or  with  commercial products may contact the
  9. author at the address below for terms.
  10.  
  11. QSORT is made available  in  the  public  domain  under  the
  12. "share-ware"  concept.  If you find this program useful, you
  13. are asked to send its author a  donation  commensurate  with
  14. its  value  to you ($10 would be nice).  This will encourage
  15. the development of other  useful,  affordable  tools.   Send
  16. checks to:
  17.  
  18.                 Ben Baker
  19.                 P.O. Box 425
  20.                 Godfrey, Il 62035
  21.  
  22. Bug reports or suggestions may be sent to the above  address
  23. or  via  FidoNet  mail  to Fido node # 100/76, Ben's Bakery.
  24. (NOTE:  This is NOT a BBS, but  does  receive  FidoNet  mail
  25. forwarded via Fido 100/51.)
  26.  
  27. Purpose:   This  filter  command  reads  text  data from the
  28.            standard input device, sorts it and writes it  to
  29.            the  standard  output device.  Optionally, it may
  30.            be used to sort a file "in place."
  31.  
  32. Format:    QSORT [filespec] [/R] [/Mlen]
  33.                             [/[L][+|-][col][:width]. . .
  34.  
  35. Type:      Internal     External
  36.                           ****
  37.  
  38. Remarks:   Sorts   are   done   using  the  ASCII  collating
  39.            sequence, or optionally using  lexical  sequence.
  40.            Tab characters are not expanded with blanks.
  41.  
  42.            Up to 30 field parameters, /[L][+|-][col][:width]
  43.            may be used to specify key fields and are ordered
  44.            major  to  minor  from left to right.  The 'L' if
  45.            present specifies  "lexical"  sequence  for  this
  46.            field.    (See  discussion  of  lexical  sequence
  47.            below.) The  minus  (-)  sign  specifies  reverse
  48.            order  for  this field.  The plus (+) sign (or no
  49.            sign) specifies normal sort order.   If  present,
  50.            [col]  defines the beginning column of the field.
  51.            If omitted, column 1  is  assumed.   If  present,
  52.            [:width]  defines the field width in columns.  If
  53.            width is omitted,  the  rest  of  the  record  is
  54.            assumed.   If  no key field parameters are given,
  55.            the entire record is  the  key  field.   Any  key
  56.            field  which falls beyond the end of a particular
  57.            record is treated as a null (zero  length)  field
  58.            for that record.
  59.  
  60.            The  /Mlen parameter allows optionally specifying
  61.            the maximum record length.  It  may  lie  in  the
  62.            range  of  /M1  to  /M3600.   The  upper bound is
  63.            necessary to permit a "worst case"  merge  to  be
  64.            done  in  a buffer less than 64 Kbytes in length.
  65.            If this parameter  is  present,  it  must  appear
  66.            before  any  field parameters.  If it is omitted,
  67.            132 is the default.  NOTE:  Maximum record length
  68.            may  be  larger than any record in the file to be
  69.            sorted, but excessive maximum record length  will
  70.            unecessarily degrade the performance of QSORT.
  71.  
  72.            The  /R  parameter  is included for compatibility
  73.            with DOS SORT and is redundant.  It reverses  the
  74.            sense of sort direction for all key fields.
  75.  
  76.            If  filespec  is  included  in  the  command, any
  77.            redirection specified will be ignored.  Disk  and
  78.            path  specifiers  may be included in filespec and
  79.            will be used for both input  and  output.   QSORT
  80.            will sort the input file defined by filespec to a
  81.            file with  an  extent  of  .$$$.   On  successful
  82.            completion of the sort, the input file is deleted
  83.            and the  output  file  is  renamed  to  filespec,
  84.            accomplishing, in effect, an "in-place" sort.
  85.  
  86.            The  /Mlen  parameter  and  field parameters must
  87.            observe the relative ordering defined above,  but
  88.            filespec, redirection and/or the /R parameter may
  89.            appear anywhere on the command line.
  90.  
  91. Examples:  Produce a directory listing  sorted  by  creation
  92.            date  and  time,  and display it on the console a
  93.            screen's worth at a time:
  94.  
  95.                A>DIR | QSORT /30:2 /24:5 /39 /34:5 | MORE
  96.  
  97.            The output of the DIR command is piped to  QSORT.
  98.            The  key  fields  defined are, from left to right
  99.            (major to minor), year (2 digits), month and day,
  100.            AM/PM flag and time.  The output of QSORT is then
  101.            piped to MORE for display.
  102.  
  103.            Next, replace the unsorted FILE.TXT with the same
  104.            data  sorted in reverse order.  Use columns 10 to
  105.            16 as the sort key:
  106.  
  107.                A>QSORT FILE.TXT /-10:7
  108.            or
  109.                A>QSORT FILE.TXT /10:7 /R
  110.            or (SORT compatible)
  111.                A>QSORT FILE.TXT /R /+10
  112.  
  113.            Finally, perform a simple sort on a file with 240
  114.            byte records (not including newline or EOL):
  115.  
  116.                A>QSORT LARGE.REC /M242
  117.  
  118.  
  119.                 --- Implementation Notes ---
  120.  
  121. QSORT is intended as an enhanced replacement for  DOS  SORT.
  122. It is nearly fully upward compatible, but provides much more
  123. flexibility.  Multiple sort keys may be specified, a  pseudo
  124. in-place  sort  may be performed and files and/or records of
  125. any  size  may  be  sorted  provided  only  that  there   is
  126. sufficient  disk  space  for work files and the output file.
  127. QSORT  uses  the  "quick  sort"  algorithm,   which   cannot
  128. guarantee  the  order  of  records whose keys are all equal.
  129. This in the  one  "incompatibility"  with  DOS  SORT,  which
  130. retains  the  original  order  of  records when its only key
  131. compares equal.  This is important to SORT because  it  must
  132. be  invoked  multiple  times  to effect a multiple key sort.
  133. With QSORT you only sort once, and there are usually  enough
  134. keys  available  to  insure  you  get the order you want the
  135. first time.
  136.  
  137. QSORT uses a sort buffer of about 60K bytes, and  will  fill
  138. the  buffer as full as possible, and then sorts the contents
  139. of the buffer.  If it has reached the end of the input  file
  140. and  has  not  yet generated any work files, the contents of
  141. the buffer are written to the output  file,  completing  the
  142. sort operation.
  143.  
  144. If  the input file is too large to fit into the sort buffer,
  145. as much of the input file  as  possible  is  read  into  the
  146. buffer, sorted, then written to a temporary work file.  This
  147. process is repeated as many times as  necessary  to  process
  148. the  entire  input  file, each time creating a new work file
  149. for the sorted output.
  150.  
  151. Upon completion of the "sort phase," QSORT begins  a  "merge
  152. phase."  Each  work  file  is  a sorted sub-set of the input
  153. file.   Thus,  work  files  may  be  read  sequentially  and
  154. comnbined  to  produce  a sorted output.  QSORT will open as
  155. many work files as DOS permits (more on this later).  If all
  156. the remaining work files can be opened, the sorted result is
  157. written to the output file.  Otherwise, a new work  file  is
  158. created  and  another  merge pass will be required.  On each
  159. merge  pass,  the  number  of  work  files  is  reduced  and
  160. eventually  all  remaining work files will be opened and the
  161. sorted output file  will  be  written  completing  the  sort
  162. operation.
  163.  
  164. QSORT  is  smart  enough  to  never  have just one work file
  165. remaining,  which  would   require   an   unnecessary   copy
  166. operation.
  167.  
  168. QSORT,  to  work  properly, needs enough space on the output
  169. disk to hold the output file.  Even if the input file is  to
  170. be  deleted  and  resides in the same directory, that is not
  171. done until after  the  output  file  has  been  successfully
  172. written.   If  one  merge  pass  is  required,  the  default
  173. directory should have about 10% more space than the size  of
  174. the  input file for work files.  If more than one merge pass
  175. will be required, allow about twice the size  of  the  input
  176. file  as  work file space on the default disk.  If QSORT has
  177. an error, it  will  terminate  with  the  input  file  still
  178. intact, and will return to DOS with ERRORLEVEL = 1.
  179.  
  180. Each  time  QSORT  must create a new work file, the data put
  181. into it must be processed again.  Obviously, the more  files
  182. QSORT  can  open  during  the merge phase, the faster it can
  183. sort large files.  If DOS is properly preconditioned,  QSORT
  184. can  have  up  to 15 work files open at once, and very large
  185. files can be sorted with just one sort pass  and  one  merge
  186. pass.  Unfortunately, that capability is not automatic.
  187.  
  188. DOS  has a fixed number of file "handles" that it associates
  189. with open files.  The default number is eight, but DOS opens
  190. five  of  them for standard input, standard output, standard
  191. error, standard printer and standard auxiliary device.  That
  192. leaves  three  for merging.  A 250K input file would produce
  193. five work files and that  would  take  three  merge  passes;
  194. merge  two  into  one,  leaving  four;   merge  two into one
  195. leaving three;  and finally  merge  three  into  the  output
  196. file.
  197.  
  198. Worse  yet,  since  you  need  at  least  three  handles for
  199. merging, if you have resident programs that have open  files
  200. you can't merge at all!
  201.  
  202. DOS  can  be  told to set aside more space for file handles.
  203. Each handle is only 39  bytes  and  it's  memory  very  well
  204. spent.  One process can have a maximum of 20 handles open at
  205. one time, but since resident processes may be using handles,
  206. I recommend 25 to 35.  To do this, the root directory of the
  207. DISK OR DISKS YOU  BOOT  FROM  must  contain  a  file  named
  208. CONFIG.SYS.    If  your  boot  disk(s)  already  contains  a
  209. CONFIG.SYS, edit it, or if not, create  it  to  contain  the
  210. following line:
  211.  
  212.      FILES=25 (or more)
  213.  
  214. While  we're  at  it, let's add one more thing to CONFIG.SYS
  215. which will improve the performance of QSORT and  many  other
  216. programs  as  well.   DOS  provides,  by  default,  two disk
  217. buffers.  These are the buffers it uses to do its disk reads
  218. and  writes.   During  the  merge  phase QSORT may have many
  219. files open at once, reading from them in more or less random
  220. order.   DOS  may  have  to  read  the  same physical sector
  221. several times to get all its data.   But  DOS  can  remember
  222. what's  in  each buffer and where it came from, and will not
  223. reread a sector it already has in a buffer.  DOS  needs  528
  224. bytes for each buffer.  I recommend 20 buffers to make QSORT
  225. perform well under the most adverse conditions.   This  will
  226. require  an  additional 9504 bytes or slightly more than 9K,
  227. again memory  well  spent,  so  we  add  to  CONFIG.SYS  the
  228. following line:
  229.  
  230.      BUFFERS=20
  231.  
  232. I  hope  you  find  this  program useful.  Your comments and
  233. suggestions are welcome.  My address is at the top  of  this
  234. file.   A  planned  version  2  will  provide file merge and
  235. record selection capability.   (Sort  of  a  quick-and-dirty
  236. file manager utility.)
  237.  
  238.                    Notes on Version 1.1:
  239.                    ----- -- ------- ----
  240.  
  241. QSORT  1.0  set  an arbritrary maximum record length of 132.
  242. This should certainly be enough, right?  Wrong!  The program
  243. had not been released a month before I heard from a user who
  244. needed to sort 240-byte records.  It occurred  to  me  that,
  245. for  any  reasonable  maximum  length, someone would need to
  246. sort bigger records.  The sort and merge subroutines need to
  247. know  the  maximum  size  record  to be expected in order to
  248. manage their buffers, and an unnecessarily large limit would
  249. make them wasteful of space and degrade performance.
  250.  
  251. The  solution,  of  course,  was  to add the '/M' parameter,
  252. allowing a user to specify his  own  limit  if  132  is  not
  253. enough.
  254.  
  255. One other minor change was made to the program.  Version 1.0
  256. documentation implied (in fact stated!) that  column  number
  257. could be omitted from a field parameter and would default to
  258. 1.  In other words '/1:4' and '/:4'  were  equivalent.   The
  259. program,  however,  would not accept the latter.  Since this
  260. is a useful shorthand, the program has been changed to match
  261. the documentation.
  262.  
  263.                    Notes on Version 1.2:
  264.                    ----- -- ------- ----
  265.  
  266. This version was borne out of my own need to sort files with
  267. mixed capitalization.  ASCII sequence produced some  bizzare
  268. results  when  words  beginning with 'Z' sorted before those
  269. beginning with  'a.'  Case-insensitive  sorting  isn't  much
  270. better because upper and lower case get mixed randomly.
  271.  
  272. The following table will illustrate what I mean:
  273.  
  274.      INPUT         ASCII          CASE           LEXICAL
  275.                                INSENSITIVE
  276.      
  277.      DeLaPort      Baker          Baker          Baker
  278.      Smith         Brown          brown          Brown
  279.      brown         DeAngelo       bRown          bRown
  280.      deLaPorte     DeLaPort       Brown          brown
  281.      Deangelo      Deangelo       Deangelo       DeAngelo
  282.      deAngelo      Deangelo       deangelo       Deangelo
  283.      Brown         DelaPort       Deangelo       Deangelo
  284.      smith         DelaPorte      deAngelo       deAngelo
  285.      delaPorte     Harry          DeAngelo       deangelo
  286.      DelaPort      Smith          delaPort       DeLaPort
  287.      DeAngelo      bRown          DelaPort       DelaPort
  288.      DelaPorte     brown          delaPort       delaPort
  289.      deangelo      deAngelo       DeLaPort       delaPort
  290.      Harry         deLaPorte      DelaPorte      DelaPorte
  291.      delaPort      deLaPorte      deLaPorte      deLaPorte
  292.      Baker         deangelo       delaPorte      deLaPorte
  293.      deLaPorte     delaPort       deLaPorte      delaPorte
  294.      Deangelo      delaPort       Harry          Harry
  295.      bRown         delaPorte      smith          Smith
  296.      delaPort      smith          Smith          smith
  297.  
  298. The first column is a list of names in arbitrary order.  The
  299. second is an ASCII sort of that list.   Third  we  have  one
  300. possible  case-insensitive  sort  of  the  list.  The fourth
  301. column is what I really wanted.  It is sorted the way  these
  302. words would be sorted in a dictionary (or lexicon).
  303.  
  304. The  lexical sort implemented in this version is achieved by
  305. making case-insensitive comparisions of entire fields.  Only
  306. when  a  comparison of the endire field is equal is an ASCII
  307. comparison called upon to arbitrate ties.
  308.  
  309. Lexical sorting can be very useful when needed, but be aware
  310. that  unnecessarily  specifying lexical ordering may degrade
  311. performance of QSORT.
  312.  
  313. Speaking of  performance,  QSORT  does  pretty  well.   Matt
  314. Kanter of New York reports sorting a 650K file in 40 minutes
  315. and that ain't too shabby!  Never-the-less, QSORT  has  been
  316. made  more  intelligent  in  the way it schedules merging of
  317. very very  large  files,  thus  improving  performance  when
  318. multiple  merge  passes are required, a feature that will go
  319. unnoticed by most users (sigh).
  320.